/*
 * meausre.h
 *
 *  Created on: Apr 20, 2010
 *      Author: snirgaz
 */

#ifndef MEAUSRE_H_
#define MEAUSRE_H_

#include "HelpLibs/def.h"
#include "WorldLines.h"`
#include "HelpLibs/RandomGen.h"
#include "HelpLibs/ArrayMultiD.h"
#include "HelpLibs/QmcParameters.h"
#include "SimParams.h"
#include "fftw/fftw3.h"
#include "Observable.h"
#include "HelpLibs/fftwPlan.h"
#include <algorithm>
#include <complex>

using namespace std;

typedef boost::chrono::system_clock::time_point TimePoint;
typedef boost::chrono::duration<double, boost::ratio<3600> > Hour;

class ProgressBar {
	int totalNumberOfMeasure_;
	ofstream *outFile_;
	double simTime_;
	TimePoint startTime_;
	double pc_, deltaDump_;
public:
	void init(int totalNumberOfMeasure, int minNumOfMeasure, double simTime,
			ofstream *outFile, QmcParameters qmcParameters);
	void update(int numOfMeasure, bool &endTime, bool &dumpFlag);
	void updateMinNumOfMeasure(int minNumOfMeasure);
	int getTotalNumberOfMeasure();
};

enum MeasureType {OPEN_MEASURE,CLOSED_MEASURE};

class Measure {
protected:
	MeasureType measureType_;
    WorldLines *wl_;
public:
	Measure();
	virtual void DoMeasurement()=0;
	virtual bool checkDone() const =0;
	virtual void dumpToFile(hdf5RW &hdf5File) const=0;
	virtual int getNumOfMeasure() const=0;
	virtual void readFromFile(hdf5RW &hdf5File)=0;
	MeasureType getMeasureType() const;
	virtual ~Measure();
};
class Measurements {
	typedef boost::ptr_vector<Measure> MesureVector;
	typedef MesureVector::iterator MesureVectorIter;
	//int numOfBins_;
private:
	MesureVector measures_;
	WorldLines *wl_;
	ProgressBar progBar_;
	int rateOpen_, rateClosed_;
	bool allDone_;
	ofstream *outFile_;
public:
	Measurements();
	~Measurements();
	void init(WorldLines *wl, QmcParameters &qmcParameters, ofstream *outFile);
	void DoMeasurement(bool &endTime, bool &dumpTime);
	bool checkNotDone() const;
	void dump(string outPath, bool final) const;
	void read(string outPath);
	void updateMinNumOfMeasure();
	void updateClosedRate(int const closedRate);
	int getClosedRate() const;
	void updateOpenRate(int const openRate);
	int getOpenRate() const;
};
#endif /* MEAUSRE_H_ */
